<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>监听器的使用</title>
</head>

<body>
    <script src="/js/vue.js"></script>
    <div id="app">
        <!-- Vue提供了一种通用的方式来观察和响应Vue实例上的data变化，即监听器 
        监听data值的变化，当data值变化以后就会触发，我希望vue做些事情-->
        <p>{{value}}</p>
        <button @click="value++">button</button>

        <p>{{price}}</p>
        <button @click="priceChange()">button</button>
        <p>比原价贵了{{expensive}}元</p>

        <p>{{obj.value}}</p>
        <button @click="objValueChange()">button</button>

        <p>{{list}}</p>
        <button @click="listChange()">button</button>

        <p>{{name}}</p>
        <button @click="stringChange()">button</button>

        <p>{{total}}</p>
        <p>{{total2}}</p>
    </div>

    <script>
        let app = new Vue({
            el: "#app",
            data: {
                value: 100,
                price: 100,
                expensive: 0,
                rePrice: 100,
                obj: {
                    value: 100
                },
                list: [1, 2, 3],
                name: "Shane",
                total2: 0
            },
            methods: {
                priceChange() {
                    this.price += 10
                },
                objValueChange() {
                    this.obj.value++
                },
                listChange() {
                    this.list.push(4)
                    this.list = [2, 3, 4, 5]
                },
                stringChange() {
                    this.name = "kitty"
                }
            },
            computed: {
                total() {
                    return this.value + this.price
                }
            },
            watch: {// 监听器
                // key值必须和dataname相同
                // 监听data绑定的value值，那么键的值也必须叫value
                // 键值对中值的值必须是匿名函数
                value(newValue, oldValue) {//oldValue 是监听的数据变化之前的值，newValue是监听数据变化之后的值
                    // 参数可以省略

                    console.log("value值发生了变化");
                    console.log("old:", oldValue);
                    console.log("new:", newValue);
                },
                // 案例： 有个价格price，原价100，当你点击一个按钮，价钱加10元，最后页面显示与原价比贵了多少钱。
                // price(newValue, oldValue) {
                //     this.expensive = newValue - this.rePrice
                // },
                list() {
                    console.log("数组的值发生了变化");
                },
                name() {
                    console.log("字符串的值发生了变化");
                },
                // 复杂对象 简单的监听方式是没办法监听对象的数据变化
                // obj(){
                //     console.log("obj的值发生了变化");
                // }
                // 深度监听 改用对象方式监听
                obj: {
                    // 1. deep键值对 决定此监听是否是深度监听
                    deep: true,// 深度监听：键值对值为true  普通监听： 键值对值为false 等同于简单监听 或者 说监听的语法糖
                    // 2. handler 监听方法
                    handler(newValue, oldValue) {
                        console.log("obj对象的值发生了变化");
                    },
                    immediate: true//立即执行监听器，进入页面直接执行
                },
                price: {//监听器实现计算属性
                    deep: true,
                    handler() {
                        this.total2 = this.price + this.value
                    },
                    immediate: true
                },
                total() {//监听计算属性
                    // 如果我们监听计算属性，当计算属性中data绑定的数据发生变化，则触发
                    console.log("计算属性是否发生变化");
                }


            }
        })

        // 值类型
        let a = 10
        let b = a // 地址相同
        a = 11 //改变了一个地址
        console.log(b);//10

        //  引用类型
        let c = {
            name: "shane"
        }
        let d = c // c 和 d 共用一个内存地址，地址相同
        // Object.assign(c, { age: 10 })
        c = { age: 10 }  // 通过 赋值符号 创建了一个新的地址
        console.log(d);//???

        //js数组
        let e = [1, 2, 3]
        f = e
        e.push(4)
        console.log(f);//??



    </script>
</body>

</html>